package frame.dao;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

import frame.exception.FrameException;
/**
 * 加载src.sql中所有的 sql文件。并将文件中的sql转换为kv保存在一个MAP对象中。
 * 
 * @author MR.CUIPENG
 *
 */
public class SqlLoader {
	
	private String sqlTag="--@";
	private String sqlFilePath="sql";
	private String tag="--";//注释标记
	
	private Map<String,String> sqlMap;
	
	public SqlLoader() {
		String sqlPath=SqlLoader.class.getClassLoader().getResource(sqlFilePath).getPath();
		File file = new File(sqlPath);  
        if(!file.exists()||!file.isDirectory()){  
            throw new FrameException("错误的目录路径："+sqlPath);
        }else{
        	String[] sqls=file.list();
        	sqlMap=new HashMap<String, String>();
        	for (String sqlFile : sqls) {
        		//只加载sql结尾的文件
        		if("sql".equalsIgnoreCase(sqlFile.substring(sqlFile.length()-3))){
        			analysis(sqlFilePath+"/"+sqlFile);
        		}
			}
        }  
	}
	
	private void analysis(String file) {//分析单个文件
        String id = null;
        StringBuffer sql = new StringBuffer();
        if (getInputStream(file) != null) {
             BufferedReader sqlFileReader = null;
             try {
	                 sqlFileReader = new BufferedReader(new InputStreamReader(getInputStream(file)));
	                 String currentLine = null;
	                 while ((currentLine = sqlFileReader.readLine()) != null) {// 逐行读取文件内容
	                     if (currentLine.startsWith(sqlTag)) {// 发现新的SQL语句，将已经发现的SQL语句放在SQL容器中
	                         if (id != null) {
	                                  sqlMap.put(id, sql.toString().trim());
	                                  id = null;
	                                  sql = new StringBuffer();
	                         }
	                         id = currentLine.substring(sqlTag.length()).trim();
	                     } else if (currentLine.startsWith(tag)) {
	                         continue; // 不读取注释行
	                     } else {// 非注释，ID行
	                         if (currentLine.length() > 0) {
	                            int commentsIndex = currentLine.indexOf(tag);
	                            if (commentsIndex > 0) { // 去掉SQL语句行的末尾注视
	                               currentLine = currentLine.substring(0,commentsIndex).trim();
	                            }
	                            sql.append(currentLine + " ");// 将换行符替换为空格
	                         } else {
	                           sql.append(" ");// 将换行符替换为空格
	                         }
	                      }
	                      currentLine = null;
	              }
	              if (id != null) {
	                 sqlMap.put(id, sql.toString().trim());
	              }
             } catch (IOException ioex) {
                      ioex.printStackTrace();
             } finally {
                  if(sqlFileReader != null) {
                    try {sqlFileReader.close();} catch (IOException e) {}
                  }
             }
      }
       
    }
	
	private InputStream getInputStream(String file) {
        return  getClass().getClassLoader().getResourceAsStream(file);
    }
	
	//获取当前解析sql文件使用的标记sql语句key的字符串
	public String getSqlTag() {
		return sqlTag;
	}

	/**
	 * 设置当前解析sql文件使用的标记sql语句key的字符串
	 * @param sqlTag
	 */
	public void setSqlTag(String sqlTag) {
		this.sqlTag = sqlTag;
	}
	/**
	 * 获取sql文件相对于工程的路径
	 * @return
	 */
	public String getSqlFilePath() {
		return sqlFilePath;
	}

	/**
	 * 设置sql文件相对于工程的路径
	 * @param sqlFilePath
	 */
	public void setSqlFilePath(String sqlFilePath) {
		this.sqlFilePath = sqlFilePath;
	}

	/**
	 * 获取标记注释的字符串
	 * @return
	 */
	public String getTag() {
		return tag;
	}
	/**
	 * 设置标记注释的语句
	 * @param tag
	 */
	public void setTag(String tag) {
		this.tag = tag;
	}

	/**
	 * 获取解析好的sql语句集合
	 * @return
	 */
	public Map<String, String> getSqlMap() {
		if(sqlMap==null){
			throw new FrameException("sqls不存在！sqlTag is :"+sqlTag+",sqlFilePath is :"+sqlFilePath);
		}
		return sqlMap;
	}
	
}
